<?php
namespace Erp\C\Orders\Tn\Shipping;
use Erp\C\Orders\Tn\Shipping\Shipping;
use Erp\C\Orders\Tn\Api\ApiWsModule;
use Fn;
class Ws extends Shipping{
    private $api_ws;
    //初始化API请求对象
    public function __construct(){
        $this->api_ws = new ApiWsModule();
    }
    /**
     * 获取Tn入口方法
     * @param array $Orders array(1,2,3) || string 2
     */
    public function getTn($Orders){
        if (!is_array($Orders)) {
            $Orders = array($Orders);
        }
        $count = count($Orders);
        $multi_num = 5;
        $for_num = ceil($count/$multi_num);
        for ($i=0; $i < $for_num; $i++) {
            $s = $multi_num*$i;
            $tmp_arr = array_slice($Orders,$s,$multi_num);
            $this->WsApiMgr($tmp_arr);
        }
    }
    /**
     *获取纬狮国际墨西哥专线TN流程
     *@param array $tmp_arr 数组 订单号
     */
    public function WsApiMgr($tmp_arr){
        $request_data = $this->createPackageParams($tmp_arr);//拼接数据
        Fn\App::log('kim_dsf',$request_data,"DSF获取TN数据");
        $response = $this->api_ws->createAndConfirmPackages($request_data);	//Api接口业务转化
        Fn\App::log('kim_dsf',$response,"DSF获取TN数据");
        $this->disposePackageReturn($response);	//返回的结果数据处理
    }

    /**
     * 拼接数据
     *创建线上包裹数据格式
     *@param array $tmp_arr
     *@return array
     */
    public function createPackageParams($tmp_arr){
        $o_model = A('Orders');
        foreach ($tmp_arr as $key => $ordersId) {
            $ordersInfo = $o_model->combinOrderInfo($ordersId);	//获取订单信息
            //配送方式
            $shipping = $ordersInfo['orders_shipping_method'];
            $shippingArr = $this->_shippingEnumerate($shipping);
            $shipping = $shippingArr['shipCode'];
            //订单重量，单位KG，默认为0.2
            $order_weight = round($ordersInfo['orders_weight'],3);
            //收件人地址
            $address = $ordersInfo['orders_delivery_address'].' '.$ordersInfo['orders_delivery_address2'];
            $adressArr = $this->getAllAddress($address);
            if ($adressArr['address2'] == '') {
                $adressArr['address2'] =',';
            }
            if ($adressArr['address3'] == '') {
                $adressArr['address3'] =',';
            }
            //海关
            $productList = $ordersInfo['orders_items'];
            $count = 0;
            $price = 0;
            foreach ($productList as $ordersProduct) {
                $count += $ordersProduct['orders_product_quantity'];
                $price += $ordersProduct['orders_item_total_price_usd'];
            }
            $unitPrice = $price/$count;
            $unitPrice = round($unitPrice,3);
            //申报重量
            $weight = $order_weight;
            $unitWeight = $weight/$count;
            $unitWeight = round($unitWeight,3);
            $ItemArr = array();
            foreach ($productList as $key=>$ordersProduct){
                $productId=$ordersProduct['product_id'];
                $CustomsInfo=$this->getRealCustomsName($productId);	//报关名
                $invoice_enname = $CustomsInfo['ClassnameForCustoms'];
//                $ItemArr = array(
//                    'invoice_enname'	=> $invoice_enname,//海关申报品名
//                    'invoice_weight'	=> $unitWeight,//申报重量，单位KG, 精确到三位小数
//                    'invoice_quantity'	=> $count,//数量（包裹中总商品的数量）
//                    'invoice_unitcharge'=> $unitPrice,//单价
//                );
                $ItemArr[$key] = array(
                    'invoice_enname'	=> $invoice_enname,//海关申报品名
                    'invoice_weight'	=> $unitWeight,//申报重量，单位KG, 精确到三位小数
                    'invoice_quantity'	=> $ordersProduct['orders_product_quantity'],//数量(包裹中某一类商品的数量)
                    'invoice_unitcharge'=> $unitPrice,//单价
                );
            }
            //拼接数据开始
            $paramsArr = array(
                'reference_no' 		=> $ordersId,//客户参考号
                'shipper_hawbcode'  =>'YT165112165748',//系统单号，必须YT开头
                'shipping_method'	=> $shipping,//配送方式
                'country_code'		=> $ordersInfo['orders_delivery_country_iso'],//收件人国家二字码
                'order_weight'		=> $order_weight,//订单重量
                'order_pieces'		=> 1,//外包装件数
//                'length'			=> 15,//包裹长
//                'width'				=> 10,//包裹宽
//                'height'			=> 10,//包裹高
//                'is_return'			=> 1,//是否退回,包裹无人签收时是否退回，1-退回，0-不退回
                'Consignee'			=> array(
                    'consignee_name'	=> $ordersInfo['orders_delivery_name'],//收件人姓名
                    'consignee_street'	=> $adressArr['address1'],//收件人地址1
                    'consignee_street2'	=> $adressArr['address2'],//收件人地址2
                    'consignee_street3'	=> $adressArr['address3'],//收件人地址3
                    'consignee_city'	=> $ordersInfo['orders_delivery_city'],//收件人城市
                    'consignee_province'=> $ordersInfo['orders_delivery_state'],//收货人州、省
                    'consignee_telephone'=>$ordersInfo['orders_delivery_tel'],//收件人电话
                    'consignee_postcode'=> $ordersInfo['orders_delivery_postcode']//收货人邮编
                ),
                'Shipper'			=> array(
                    'shipper_countrycode'	=> 'CN',//发件人国家二字码
                    'shipper_province'      => 'guangdong',//发件人省
                    'shipper_city'          => 'dongguan',//发件人城市
                    'shipper_street'        => '3th floor,logistical Building B, Yihong Road, Yantian Village guangdong sheng   dongguan shi  feng gang zhen',//发件人地址
                    'shipper_postcode'      => '523701',//发件人邮编
                    'shipper_name'			=> 'Jun Wang',//发件人姓名
                    'shipper_telephone'		=> '0755-25672819-8010',//发件人电话
                    'shipper_mobile'        => ''//发件人手机
                ),
                'ItemArr'			=> $ItemArr
            );
            $paramsJson = json_encode($paramsArr);
            //拼接数据结束
            $service = 'createOrder';
            $xml = $this->_xmlSoap($paramsJson,$service);
            $multi_request[$ordersId] = array('post'=>$xml,'header'=>$this->api_ws->header,'url'=>$this->api_ws->url);
            unset($xml);unset($arr);
        }
        return $multi_request;
    }
    //ERP运输方式转换成API标准的运输方式
    private function _shippingEnumerate($name){
        switch($name){
            case 'MEX_TN':
                return array('shipCode'=>'PK0002','warehouseCode'=>'','header'=>$this->api_ws->header);
            default:
                return false;
        }
    }
    /**
     *获取lable入口
     *@param array $Orders 一维数组
     */
    public function getLable($Orders){
        $this->_getPdf($Orders);
    }
    /**
     *获取tn成功后调用此方法获取面单Pdf
     *@param array $Orders 一维数组订单号
     */
    private function _getPdf($Orders){
        if(!$Orders){
            echo "无订单".__LINE__;
        }
        $this->_requestLable($Orders);//获取Lable标签
    }

    /**
     * @param $address
     * @param int $len
     * @return array
     * 收货地址
     */
    function getAllAddress($address,$len = 35){
        $arr = array();
        if(strlen($address) <= $len){
            $arr['address1'] = $address;
            $arr['address2'] = '';
            $arr['address3'] = '';
            return $arr;
        }
        if(strlen($address) > $len ){
            $words = explode(" ",$address);
            $res = $this->getStringForAddress($words,$len);
            $arr['address1'] = $res['str'];
            $words = $res['words'];
            $res = $this->getStringForAddress($words,$len);
            $arr['address2'] = $res['str'];
            $words = $res['words'];
            $arr['address3'] = implode(" ",$words);
            return $arr;
        }
    }

    function getStringForAddress($words,$len = 35){
        $str = '';
        $arr = array();
        foreach ($words as $key => $value) {
            $tmpStr = $str;
            $str .= $value.' ';
            if(strlen($str) > $len){
                $str = $tmpStr;
                break;
            } else{
                unset($words[$key]);
            }
        }
        $arr['str'] = $str;
        $arr['words'] = $words;
        return $arr;
    }
    /**
     * @param $json
     * @param $action
     * @return string
     * 拼接Xml
     */
    private function _xmlSoap($paramsJson,$service){
        $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
                <SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://www.example.org/Ec/\">
                    <SOAP-ENV:Body>
                        <ns1:callService>
                            <paramsJson>{$paramsJson}</paramsJson>
                            <appToken>{$this->api_ws->appToken}</appToken>
                            <appKey>{$this->api_ws->appKey}</appKey>
                            <service>{$service}</service>	
                    	</ns1:callService>
                   	</SOAP-ENV:Body>
               </SOAP-ENV:Envelope>";
        return $xml;
    }
    /**
     * @param $response
     * 返回结果集处理
     *  1:"待取TN",
     *	6:"TN失败",
     *	7:"已取TN",
     *	8:"PDF失败"
     *	99: 成功
     */
    public function disposePackageReturn($response){
        if ($response) {
            foreach ($response as $k => $v) {
                  //xml转化为数组
                $v = json_decode(xmltoarray($response[$k]),true);
                $ordersStatus = A('Orders')->getOrdersStatus($k);
                if ($v['ask'] == 'Success' && isset($v['ask'])) {
                    $ordersData = array();
                    $ordersData['orders_tn'] = $v['shipping_method_no'];
                    if(!$ordersData['orders_tn']) continue;
                    if($ordersStatus == '300'){
                        $ordersData['orders_status_children'] = 7;
                    }
                    A('Orders')->saveData($ordersData,$k);
                    $ordersShippingExtendArr = $v['order_code'];
                    //查询扩展数据是否存在
                    $info = A('orders_shipping_extend')->getExtendValue($k);
                    if($info){
                        //修改扩展数据
                        A('orders_shipping_extend')->saveExtendValue($k,$ordersShippingExtendArr);
                    }else{
                        //新增扩展数据
                        A('orders_shipping_extend')->addExtendValue($k,$ordersShippingExtendArr);
                    }
                    A('Orders')->saveOrderHistory($k,"获取纬狮国际墨西哥专线 TN成功--".$ordersData['orders_tn']);
                }else{
                    $errorsMsgs = $v['Error']['errMessage'];
                    $return = strpos($errorsMsgs,'参考单号已存在');
                    if($return !== false){
                        $this->_findTn($k);continue;
                    }
                    $ordersData = array();
                    $errorsMsgs = $v['Error']['errMessage'];
                    if ($ordersStatus == '300') {
                        $ordersData['orders_status_children'] = 6;
                        A('Orders')->saveData($ordersData,$k);
                    }
                    A('Orders')->saveOrderHistory($k,"获取纬狮国际墨西哥专线 TN失败--".$errorsMsgs);
                }
            }
        }
    }

    /**
     *已经生成过TN的订单会调用此方法查询该订单对应的TN号
     *@param   string $Orderid  字符串 传入订单号
     */
    private function _findTn($ordersId){
        $referenceNoArr = A('orders_shipping_extend')->getExtendValue($ordersId);
        $json = json_encode(array('reference_no'=>$referenceNoArr['extend_value']));
        $action = 'getOrder';
        $xml = $this->_xmlSoap($json,$action);
        $response = $this->api_ws->findTnCreatePackage($xml,$ordersId);
        $this->disposeFindPackageReturn($response);	//设置响应信息
    }
    public function disposeFindPackageReturn($response){
            foreach ($response as $k => $v) {
                $v = json_decode(xmltoarray($v),true);
                $ordersStatus = A('Orders')->getOrdersStatus($k);
                if($v['ask'] == 'Success' && isset($v['ask'])){
                    $ordersData = array();
                    $ordersData['orders_tn'] = $v['data']['shipping_method_no'];
                    if(!$ordersData['orders_tn'])continue;
                    if($ordersStatus == '300'){
                        $ordersData['orders_status_children'] = 7;
                    }
                    A('Orders')->saveData($ordersData,$k);
                    A('Orders')->saveOrderHistory($k,"获取纬狮国际墨西哥专线TN成功--".$ordersData['orders_tn']);
                }else{
                    $ordersData = array();
                    $errorsMsgs = $v['Error']['errMessage'];
                    if($ordersStatus == '300'){
                        $ordersData['orders_status_children'] = 6;
                        A('Orders')->saveData($ordersData,$k);
                    }
                    A('Orders')->saveOrderHistory($k,"获取纬狮国际墨西哥专线TN失败--".$errorsMsgs);
                }
            }
        }

    /**
     * @param $orders
     * 面单接口请求
     */
    private function _requestLable($orders){
        $ordersM=A('Orders');
        $res = $ordersM->getOrders($orders);
        $root_dir = "./Public/Data/Files/";
        foreach ($res as $k =>$v) {
            $ordersId = $v['orders_id'];
            $time = $v['orders_import_time'];
            $dir_local_root = $root_dir.date('Ymd',$time)."/";
            $filename = $ordersId.'.pdf';
            //删除PDF
            if(file_exists($dir_local_root.$filename)){
                @unlink($dir_local_root.$filename);
            }
            $paramsArr = array(
                'reference_no' 	=> $v['orders_tn'],
                'label_type'	=> 1,
//                'order_type'	=> 3
            );
            $paramsJson = json_encode($paramsArr);
            $service = 'getLabelUrl';
            $xml = $this->_xmlSoap($paramsJson,$service);
            $response = $this->api_ws->createPackageLable($xml);
            $response = $this->_delSoapheader($response,'<response>','</response>');
            $response = $this->xmlDecode($response,true);
            $response = json_decode($response[0],true);
            $contentUrl = $response['url'];
            $content = file_get_contents($contentUrl);
            $is_exists = $this->saveShippingLable($dir_local_root,$filename,$content);   // 把获得的面单pdf保存到指定目录
            Fn\App::log('ws_dff_error',array(
                'response'=>$response,
                'isExists'=>$is_exists,
                'url'=>$dir_local_root.$filename
            ),"纬狮请求PDF调试");
            if(!$is_exists){
                sleep(2);
                $response = $this->api_ws->createPackageLable($xml);
                $response = $this->_delSoapheader($response,'<response>','</response>');
                $response = $this->xmlDecode($response,true);
                $response = json_decode($response[0],true);
                $contentUrl = $response['url'];
                $content = file_get_contents($contentUrl);
                $is_exists = $this->saveShippingLable($dir_local_root,$filename,$content);
            }
            if($is_exists){
                $saveData = array();
                $saveData['orders_pdf_exist'] = 1;
                $ordersStatus = $v["orders_status"];
                if($ordersStatus == '300'){
                    $saveData['orders_status_children'] = 99;
                }
                A('Orders')->saveData($saveData,$v['orders_id']);
                A('Orders')->saveOrderHistory($ordersId,'获取纬狮墨西哥专线PDF成功');
            }else{
                $saveData = array();
                $ordersStatus = $v['orders_status'];
                if($ordersStatus == '300'){
                    $saveData['orders_status_children'] = 8;
                }
                A('Orders')->saveData($saveData,$v['orders_id']);
                A('Orders')->saveOrderHistory($ordersId,'获取纬狮墨西哥专线PDF成功');
            }
        }
    }

    //去掉返回的xml数据的soap头部信息
    private function _delSoapheader($xml,$mark1,$mark2){
        $st = stripos($xml,$mark1);
        $ed = stripos($xml,$mark2);
        if(($st===false||$ed===false)||$st>=$ed){
            return 0;
        }
        $xml = substr($xml,($st),($ed-$st+strlen($mark2)));
        return $xml;
    }
}